package com.gdit.util;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gdit.comm.exception.BizException;
import com.gdit.comm.result.ResultCode;

import java.io.Serializable;

/**
 * @author wx
 */
public class CheckEntityUtil {

    /**
     * 通过列名查询单条记录，判断记录是否为空，如果为空则抛出异常
     *
     * @param column     数据库表的列名
     * @param value      需要查询的实际值
     * @param service    service对象
     * @param resultCode resultCode枚举类
     * @param <S>        Service类继承于 IService
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <S extends IService<T>, T> T isNullByColumnEq(String column, Object value, S service, ResultCode resultCode) {
        return judgeNullByColumnEq(column, value, service, resultCode, false);
    }

    /**
     * 通过列名查询单条记录，判断记录是否非空，如果非空则抛出异常
     *
     * @param column     数据库表的列名
     * @param value      需要查询的实际值
     * @param service    service对象
     * @param resultCode resultCode枚举类
     * @param <S>        Service类继承于 IService
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <S extends IService<T>, T> T isNotNullByColumnEq(String column, Object value, S service, ResultCode resultCode) {
        return judgeNullByColumnEq(column, value, service, resultCode, true);
    }

    /**
     * 通过条件构造器查询单条记录，判断记录是否非空，如果非空则抛出异常
     *
     * @param queryWrapper     条件构造器
     * @param service    service对象
     * @param resultCode resultCode枚举类
     * @param <S>        Service类继承于 IService
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <S extends IService<T>, T> T isNotNullQueryWrapper(QueryWrapper<T> queryWrapper, S service, ResultCode resultCode) {
        return judgeNullByQueryWrapper(queryWrapper, service, resultCode, true);
    }
    /**
     * 通过条件构造器查询单条记录，判断记录是否为空，如果为空则抛出异常
     *
     * @param queryWrapper     条件构造器
     * @param service    service对象
     * @param resultCode resultCode枚举类
     * @param <S>        Service类继承于 IService
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <S extends IService<T>, T> T isNullQueryWrapper(QueryWrapper<T> queryWrapper, S service, ResultCode resultCode) {
        return judgeNullByQueryWrapper(queryWrapper, service, resultCode, false);
    }

    /**
     * 通过主键查询单条记录，判断记录是否为空，如果为空则抛出异常
     *
     * @param id         主键值
     * @param service    service对象
     * @param resultCode resultCode枚举类
     * @param <S>        Service类继承于 IService
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <S extends IService<T>, T> T isNullById(Object id, S service, ResultCode resultCode) {
        return judgeNullById(id, service, resultCode, false);
    }

    /**
     * 通过主键查询单条记录，判断记录是否非空，如果不为空则抛出异常
     *
     * @param id         主键值
     * @param service    service对象
     * @param resultCode resultCode枚举类
     * @param <S>        Service类继承于 IService
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <S extends IService<T>, T> T isNotNullById(Object id, S service, ResultCode resultCode) {
        return judgeNullById(id, service, resultCode, true);
    }

    private static <S extends IService<T>, T> T judgeNullById(Object o, S s, ResultCode resultCode, boolean isNotNull) {
        T t = null;
        if (o != null) {
            t = s.getById((Serializable) o);
            if (!isNotNull && t == null) {
                throw new BizException(resultCode);
            } else if (isNotNull && t != null) {
                throw new BizException(resultCode);
            }
        }
        return t;
    }

    private static <S extends IService<T>, T> T judgeNullByColumnEq(String column, Object o, S s, ResultCode resultCode, boolean isNotNull) {
        T t = null;
        if (o != null) {
            t = s.getOne(new QueryWrapper<T>().eq(column, o));
            if (!isNotNull && t == null) {
                throw new BizException(resultCode);
            } else if (isNotNull && t != null) {
                throw new BizException(resultCode);
            }
        }
        return t;
    }

    private static <S extends IService<T>, T> T judgeNullByQueryWrapper(QueryWrapper<T> queryWrapper, S s, ResultCode resultCode, boolean isNotNull) {
        T t = s.getOne(queryWrapper);
        if (!isNotNull && t == null) {
            throw new BizException(resultCode);
        } else if (isNotNull && t != null) {
            throw new BizException(resultCode);
        }

        return t;
    }

    /**
     * 通过列名查询单条记录，判断记录是否为空，如果为空则抛出异常
     *
     * @param column     数据库表的列名
     * @param value      需要查询的实际值
     * @param mapper    mapper对象
     * @param resultCode resultCode枚举类
     * @param <M>        Mapper类继承于 BaseMapper
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <M extends BaseMapper<T>, T> T isNullByColumnEq(String column, Object value, M mapper, ResultCode resultCode) {
        return judgeNullByColumnEq(column, value, mapper, resultCode, false);
    }

    /**
     * 通过列名查询单条记录，判断记录是否非空，如果非空则抛出异常
     *
     * @param column     数据库表的列名
     * @param value      需要查询的实际值
     * @param mapper    mapper对象
     * @param resultCode resultCode枚举类
     * @param <M>        Mapper类继承于 BaseMapper
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <M extends BaseMapper<T>, T> T isNotNullByColumnEq(String column, Object value, M mapper, ResultCode resultCode) {
        return judgeNullByColumnEq(column, value, mapper, resultCode, true);
    }

    /**
     * 通过条件构造器查询单条记录，判断记录是否非空，如果非空则抛出异常
     *
     * @param queryWrapper     条件构造器
     * @param mapper    mapper对象
     * @param resultCode resultCode枚举类
     * @param <M>        Mapper类继承于 BaseMapper
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <M extends BaseMapper<T>, T> T isNotNullQueryWrapper(QueryWrapper<T> queryWrapper, M mapper, ResultCode resultCode) {
        return judgeNullByQueryWrapper(queryWrapper, mapper, resultCode, true);
    }

    /**
     * 通过条件构造器查询单条记录，判断记录是否为空，如果为空则抛出异常
     *
     * @param queryWrapper     条件构造器
     * @param mapper    mapper对象
     * @param resultCode resultCode枚举类
     * @param <M>        Mapper类继承于 BaseMapper
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <M extends BaseMapper<T>, T> T isNullQueryWrapper(QueryWrapper<T> queryWrapper, M mapper, ResultCode resultCode) {
        return judgeNullByQueryWrapper(queryWrapper, mapper, resultCode, false);
    }

    /**
     * 通过主键查询单条记录，判断记录是否为空，如果为空则抛出异常
     *
     * @param id         主键值
     * @param mapper    mapper对象
     * @param resultCode resultCode枚举类
     * @param <M>        Mapper类继承于 BaseMapper
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <M extends BaseMapper<T>, T> T isNullById(Object id, M mapper, ResultCode resultCode) {
        return judgeNullById(id, mapper, resultCode, false);
    }

    /**
     * 通过主键查询单条记录，判断记录是否非空，如果不为空则抛出异常
     *
     * @param id         主键值
     * @param mapper    mapper对象
     * @param resultCode resultCode枚举类
     * @param <M>        Mapper类继承于 BaseMapper
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <M extends BaseMapper<T>, T> T isNotNullById(Object id, M mapper, ResultCode resultCode) {
        return judgeNullById(id, mapper, resultCode, true);
    }

    private static <M extends BaseMapper<T>, T> T judgeNullById(Object o, M mapper, ResultCode resultCode, boolean isNotNull) {
        T t = null;
        if (o != null) {
            t = mapper.selectById((Serializable) o);
            if (!isNotNull && t == null) {
                throw new BizException(resultCode);
            } else if (isNotNull && t != null) {
                throw new BizException(resultCode);
            }
        }
        return t;
    }

    private static <M extends BaseMapper<T>, T> T judgeNullByColumnEq(String column, Object o, M mapper, ResultCode resultCode, boolean isNotNull) {
        T t = null;
        if (o != null) {
            t = mapper.selectOne(new QueryWrapper<T>().eq(column, o));
            if (!isNotNull && t == null) {
                throw new BizException(resultCode);
            } else if (isNotNull && t != null) {
                throw new BizException(resultCode);
            }
        }
        return t;
    }

    private static <M extends BaseMapper<T>, T> T judgeNullByQueryWrapper(QueryWrapper<T> queryWrapper, M mapper, ResultCode resultCode, boolean isNotNull) {
        T t = mapper.selectOne(queryWrapper);
        if (!isNotNull && t == null) {
            throw new BizException(resultCode);
        } else if (isNotNull && t != null) {
            throw new BizException(resultCode);
        }

        return t;
    }

}
